/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved.
 * secGear is licensed under the Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *     http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
 * PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

#include <stdio.h>
#include <unistd.h>
#include <linux/limits.h>
#include "enclave.h"
#include "helloworld_u.h"
#include "string.h"
#include "qingtian_enclave.h"

#define BUF_LEN 32

int main()
{
    char *path = PATH;
    cc_enclave_t *context = NULL;
    context = (cc_enclave_t *)malloc(sizeof(cc_enclave_t));
    if (!context) {
        return CC_ERROR_OUT_OF_MEMORY;
    }
    cc_enclave_result_t res;

    printf("Create secgear enclave\n");

    char real_p[PATH_MAX];
    /* check file exists, if not exist then use absolute path */
    if (realpath(path, real_p) == NULL) {
	    if (getcwd(real_p, sizeof(real_p)) == NULL) {
		    printf("Cannot find enclave.sign.so");
		    return -1;
	    }
	    if (PATH_MAX - strlen(real_p) <= strlen("/enclave.signed.so")) {
		    printf("Failed to strcat enclave.sign.so path");
		    return -1;
	    }
	    (void)strcat(real_p, "/enclave.signed.so");
    }
    enclave_features_t features[2];
    features[0].setting_type = QINGTIAN_STARTUP_FEATURES;
    qingtian_startup_t pra;
    pra.cpus = 4;
    pra.enclave_cid = 4;
    pra.mem_mb = 2048;
    pra.ip = "127.0.0.1";
    pra.port = 8082;
    features[0].feature_desc = &pra;

    res = cc_enclave_create(real_p, QINGTIAN_ENCLAVE_TYPE, 0, SECGEAR_DEBUG_FLAG, &features[0], 1, context);
    if (res != CC_SUCCESS) {
        printf("Create enclave error\n");
        return res;
    }
    int  retval = 0;
    char buf[BUF_LEN];
    res = get_string(context, &retval, buf);
    if (res != CC_SUCCESS) {
        printf("Ecall enclave error\n");
    } else {
        printf("return val = %d, buf[len = %zu] %s\n", retval, strlen(buf), buf);
    }

    int a = 11;
    int b = 22;
    int rval = 0;
    res = get_add(context, &rval, a, b);
    if (res != CC_SUCCESS) {
        printf("Ecall enclave error\n");
    } else {
        printf("sum is %d\n", rval);
    }

    int64_t a_int64 = 111;
    int64_t b_int64 = 222;
    int64_t rval_int64 = 0;
    res = get_add_int64(context, &rval_int64, a_int64, b_int64);
    if (res != CC_SUCCESS) {
        printf("Ecall enclave error\n");
    } else {
        printf("sum is %ld\n", rval_int64);
    }

    uint64_t a_uint64 = 1111;
    uint64_t b_uint64 = 2222;
    uint64_t rval_uint64 = 0;
    res = get_add_uint64(context, &rval_uint64, a_uint64, b_uint64);
    if (res != CC_SUCCESS) {
        printf("Ecall enclave error\n");
    } else {
        printf("sum is %lu\n", rval_uint64);
    }

    size_t a_size = 11111;
    size_t b_size = 22222;
    size_t rval_size = 0;
    res = get_add_uint64(context, &rval_size, a_size, b_size);
    if (res != CC_SUCCESS) {
        printf("Ecall enclave error\n");
    } else {
        printf("sum is %zu\n", rval_size);
    }

    res = cc_enclave_destroy(context);
    if(res != CC_SUCCESS) {
        printf("Destroy enclave error\n");
    }
    return res;
}
